package com.wlr.blog.article.service.impl;

import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch._types.query_dsl.Operator;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.elasticsearch.core.search.HighlightField;
import co.elastic.clients.elasticsearch.core.search.Hit;
import com.wlr.blog.util.common.strategy.SearchStrategy;
import com.wlr.blog.web.common.entity.Article;
import com.wlr.blog.web.common.vo.ArticleSearchVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author lrwang
 * @version 1.0
 * @date 2022/11/21 21:59
 */
@Service("esServiceImpl")
@Slf4j
public class EsArticleSearch extends SearchStrategy<Article> {
    @Autowired
    ElasticsearchClient elasticsearchClient;
    /**
     * 高亮标签
     */
    public static final String PRE_TAG = "<span style='color:#f47466'>";
    /**
     * 高亮标签
     */
    public static final String POST_TAG = "</span>";

    @Override
    public List<Article> search(String keywords) {
        try {
            SearchResponse<Article> search = elasticsearchClient.search(i -> i
                    .index("article")
                    .query(q -> q
                            .multiMatch(mmb -> mmb
                                    .fields("articleTitle", "articleContent")
                                    .query(keywords)
                                    .operator(Operator.Or))
                    )
                    .highlight(hl -> hl
                            .preTags(PRE_TAG)
                            .postTags(POST_TAG)
                            .requireFieldMatch(false)
                            .fields("articleTitle", hfb -> hfb)
                            .fields("articleContent", hfb -> hfb)), Article.class);
            List<Hit<Article>> hits = search.hits().hits();
            List<Article> collect = hits.stream().map(t -> {
                Map<String, List<String>> highlight = t.highlight();
                Article source = t.source();
                List<String> articleTitle = highlight.get("articleTitle");
                assert source != null;
                if (Objects.nonNull(articleTitle)) {
                    source.setArticleTitle(articleTitle.toString());
                    log.info("articleTitle is {}", articleTitle);
                }
                List<String> articleContent = highlight.get("articleContent");
                if (Objects.nonNull(articleContent)) {
                    source.setArticleContent(articleContent.toString());
                    log.info("articleContent is {}", articleContent);
                }
                return source;
            }).collect(Collectors.toList());

            return collect;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}